package com.fram.service.admin.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.fram.bean.admin.user.request.LoginRequest;
import com.fram.bean.admin.user.request.RegisterAdminUserRequest;
import com.fram.bean.admin.user.request.UpdateAdminUserPasswordRequest;
import com.fram.bean.admin.user.response.LoginResponse;
import com.fram.common.auth.UserAuthMethod;
import com.fram.common.canstant.ErrCode;
import com.fram.common.canstant.PublicConstant;
import com.fram.common.exception.ProAffairException;
import com.fram.common.exception.ProException;
import com.fram.common.exception.ProRunTimeException;
import com.fram.common.exception.ProValiDataException;
import com.fram.common.util.PublicMethod;
import com.fram.common.util.base.BaseService;
import com.fram.common.util.json.JSONTools;
import com.fram.entity.AdminMenuPermission;
import com.fram.entity.AdminUserRole;
import com.fram.entity.User;
import com.fram.entity.UserLogin;
import com.fram.mapper.AdminMenuPermissionMapper;
import com.fram.mapper.AdminUserRoleMapper;
import com.fram.mapper.UserLoginMapper;
import com.fram.mapper.UserMapper;
import com.fram.service.admin.AdminUserService;

/**
 * @作者： 陳曉鬆 @时间： 2020年5月7日 - 上午11:07:18 @description：->
 */
@Service("adminUserService")
public class AdminUserServiceImpl extends BaseService implements AdminUserService {

	@Autowired
	private AdminMenuPermissionMapper menuPermissionMapper;

	@Autowired
	private AdminUserRoleMapper userRoleMapper;

	@Autowired
	private UserMapper adminUserMapper;
	@Autowired
	private UserLoginMapper userLoginMapper;
	
	@Override
	public LoginResponse login(LoginRequest request) throws ProException {
		if (StringUtils.isEmpty(request.getUserName()) || StringUtils.isEmpty(request.getEncryptionPwd())) {
			throw new ProValiDataException(ErrCode.ERR_PARAMETER.getReturnCode(), ErrCode.ERR_PARAMETER.getReturnMsg());
		}
		LoginResponse adminUser = adminUserMapper.selectByUserName(request.getUserName());
		if (StringUtils.isEmpty(adminUser)) {
			throw new ProValiDataException(ErrCode.USER_IS_NOT_EXISTL.getReturnCode(), ErrCode.USER_IS_NOT_EXISTL.getReturnMsg());
		}
		Integer state = adminUser.getStatus();
		if (state != 1) {
			throw new ProValiDataException(ErrCode.USER_IS_EXCEPTION.getReturnCode(), ErrCode.USER_IS_EXCEPTION.getReturnMsg());
		}
		String vatePwd = PublicMethod.getMd5(request.getEncryptionPwd() + adminUser.getCreateTime().getTime(), 1, true);
		if (!vatePwd.equals(adminUser.getPassWord())) {
			throw new ProValiDataException(ErrCode.USER_LOGIN_PASSWORD_FAIL.getReturnCode(), ErrCode.USER_LOGIN_PASSWORD_FAIL.getReturnMsg());
		}
		adminUser.setUpdateTime(new Date());
		User user = new User();
		user.setId(adminUser.getId());
		user.setLastLoginTime(adminUser.getUpdateTime());
		adminUserMapper.updateByPrimaryKeySelective(user);
		String key = UserAuthMethod.getLoginRedisKey("BACK" + (StringUtils.isEmpty(adminUser.getUserName()) ? adminUser.getPhone() : adminUser.getUserName()), adminUser.getId())
				+ "_" + adminUser.getUserName();
		String token = UserAuthMethod.getLoginToken(key, user.getLastLoginTime().getTime());
		if (ErrCode.ERR.getReturnMsg().equals(token)) {
			throw new ProValiDataException(ErrCode.USER_LOGIN_FAIL.getReturnCode(), ErrCode.USER_LOGIN_FAIL.getReturnMsg() + ":TOKEN错误");
		}
		PublicMethod.getResponse().setHeader(UserAuthMethod.LOGIN_TOKEN_NAME, token);
		PublicMethod.getResponse().setHeader("Access-Control-Expose-Headers", UserAuthMethod.LOGIN_TOKEN_NAME);
		redisService.set(UserAuthMethod.LOGIN_REDIS_DB, key, JSONTools.obj2json(adminUser), UserAuthMethod.LOGIN_REDIS_TIME);
		adminUser.setPassWord(null);
		adminUser.setUserPermissionUrl(null);
		return adminUser;
	}

	@Override
	public List<AdminMenuPermission> userMenu(Long userId, Long parentId) throws ProException {
		if (parentId == null) {
			parentId = 0L;
		}
		Map<String, Object> param = new HashMap<>();
		param.put("userId", userId);
		param.put("parentId", parentId);
		List<AdminMenuPermission> menu = menuPermissionMapper.selectForMenu(param);
		if (menu == null || menu.size() == 0) {
			throw new ProValiDataException(ErrCode.NO_DATA.getReturnCode(), ErrCode.NO_DATA.getReturnMsg());
		}
		return menu;
	}

	@Override
	@Transactional
	public void registerAdminUser(RegisterAdminUserRequest user) throws ProAffairException {
		User u = new User();
		u.setNickName(user.getName());
		u.setPhone(user.getPhone());
		u.setSex(user.getSex());
		u.setHeadImageUrl(user.getHeadImg());
		u.setStatus(1);
		u.setUserType(PublicConstant.USER_TYPE_2);
		if (adminUserMapper.insertSelective(u) <= 0 || u.getId() == null) {
			throw new ProRunTimeException(ErrCode.FAIL.getReturnCode(), "注册失败");
		}
		UserLogin login = new UserLogin();
		login.setLoginType(PublicConstant.LOGIN_TYPE_3);
		login.setUserId(u.getId());
		login.setCreateTime(new Date((System.currentTimeMillis() / 1000) * 1000));
		login.setAccount(user.getUserName());
		String vatePwd = PublicMethod.getMd5(user.getPassWord() + login.getCreateTime().getTime(), 1, true);
		login.setPassword(vatePwd);
		try {
			if (userLoginMapper.insertSelective(login) == 0) {
				throw new ProRunTimeException(ErrCode.FAIL.getReturnCode(), "注册失败");
			}
		} catch (DataAccessException e) {
			throw new ProRunTimeException(ErrCode.ERR_HAVE_EXISTED.getReturnCode(), ErrCode.ERR_HAVE_EXISTED.getReturnMsg());
		}
		AdminUserRole userRole = new AdminUserRole();
		userRole.setRoleId(user.getRoleId());
		userRole.setUserId(u.getId());
		if (userRoleMapper.insertSelective(userRole) == 0) {
			throw new ProRunTimeException(ErrCode.FAIL.getReturnCode(), "记录角色失败");
		}
	}

	@Override
	public void logout(String key) throws ProException {
		redisService.remove(UserAuthMethod.LOGIN_REDIS_DB, key);
	}

	@Override
	public void updatePassword(UpdateAdminUserPasswordRequest request, String key) throws ProException {
		LoginResponse userLogin = adminUserMapper.selectByUserIdForAdmin(request.getUserId());
		Integer state = userLogin.getStatus();
		if (state != 1) {
			throw new ProValiDataException(ErrCode.USER_IS_EXCEPTION.getReturnCode(), ErrCode.USER_IS_EXCEPTION.getReturnMsg());
		}
		String vatePwd = PublicMethod.getMd5(request.getOldPwd() + userLogin.getCreateTime().getTime(), 1, true);
		if (!vatePwd.equals(userLogin.getPassWord())) {
			throw new ProValiDataException(ErrCode.USER_LOGIN_PASSWORD_FAIL.getReturnCode(), "旧" + ErrCode.USER_LOGIN_PASSWORD_FAIL.getReturnMsg());
		}
		UserLogin login = new UserLogin();
		login.setLId(userLogin.getLId());
		login.setPassword(PublicMethod.getMd5(request.getNewPwd() + userLogin.getCreateTime().getTime(), 1, true));
		if (userLoginMapper.updatePassword(login) == 0) {
			throw new ProValiDataException(ErrCode.FAIL.getReturnCode(), "修改密码失败");
		}
		logout(key);
	}

}
